package com.example.gokchinesefoodmappcdev.filter;


import cn.hutool.json.JSONUtil;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.gokchinesefoodmappcdev.util.JWTUtil;
import com.example.gokchinesefoodmappcdev.util.ResultData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;


/*
* 自定义的JWT token 的校验过滤器
*    每次请求，验证token的合法性，如果不合法，让其重新登录
*    如果合法，说明用户处理登录状态，并将token中过的用户数据取出，存入到securityContextHolder中，以便后续验证
* */
@Component
@Slf4j
public class JWTTokenAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    JWTUtil jwtUtil;


    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {

        response.setContentType("application/json;charset=utf8");

//        System.out.println(request.getHeader("jwtToken"));
        String token = request.getHeader("token");
//         String token = request.getParameter("token");
        /*
        * 如果没有值，则直接将验证操作交给spring security后续的过滤器处理
        *      当然结果肯定是让其登录
        * */
        if(token==null){
            filterChain.doFilter(request,response);
            return;
        }
        //验证token是否有效
        try {
            jwtUtil.verify(token);
        }catch (JWTVerificationException e){
            log.error(e.getMessage(),e.getCause());
            ResultData resultData = ResultData.fail("token有误，请登录后在做尝试");
            response.getWriter().println(JSONUtil.toJsonStr(resultData));

            return;
        }

        //取出token的用户信息
        String username = jwtUtil.getValue(token, "username", String.class);
        String[] roles = jwtUtil.getArrayValue(token, "roles", String.class);

        //存入securityContextHolder

        Collection<GrantedAuthority> authorities=new HashSet<>();
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }

        User user = new User(username, "", true, true, true, true, authorities);
        UsernamePasswordAuthenticationToken authentication=new UsernamePasswordAuthenticationToken(user,null,authorities);

        SecurityContextHolder.getContext().setAuthentication(authentication);

        //放行
        filterChain.doFilter(request,response);

    }
}
